<!DOCTYPE html>
<html lang="en">
<head>

<meta charset="utf-8">
<title>Prefix free: Break free from CSS vendor prefix hell!</title>
<link rel="stylesheet" href="css/style.css" />
<link rel="stylesheet" href="css/print.css" media="print" />
<link rel="shortcut icon" href="img/favicon.png" />
<script src="prefixfree.js"></script>
<style>
	body {
		transform:none; /* Just to test embedded styles */
	}	
</style>

</head>
<body>

<hgroup>
	<h1>-prefix-free</h1>
	<h2>Break free from CSS prefix hell!</h2>
</hgroup>

<a href="https://raw.github.com/LeaVerou/prefixfree/gh-pages/prefixfree.min.js" class="download" title="Click to download" download="prefixfree.min.js">Only <strong>2KB</strong> gzipped</a>
<a href="https://github.com/LeaVerou/prefixfree" target="_blank" class="github-ribbon"><img src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png" alt="Fork me on GitHub"></a>

<p id="wtf">
	<strong>-prefix-free</strong> lets you use only unprefixed CSS properties everywhere. 
	It works behind the scenes, adding the current browser’s prefix to any CSS code, only when it’s needed.
</p>

<nav>
	Learn more:<ul>
		<li><a href="#">Home</a></li>
		<li><a href="#test-drive">Test drive</a></li>
		<li><a href="#faq">FAQ</a></li>
		<li><a href="#plugins">Plugins</a></li>
	</ul>
</nav>

<blockquote cite="http://twitter.com/#!/meyerweb/status/124618575263711232">
	<p>“[-prefix-free is] fantastic, top-notch work! Thank you for creating and sharing it.”</p>
	— <a href="http://twitter.com/#!/meyerweb/status/124618575263711232" target="_blank">Eric Meyer</a>
</blockquote>

<div class="section-container">
<section id="features">
	<h1>Features</h1>
	<ul class="features">
		<li>Processes every stylesheet in <code>&lt;link&gt;</code> or <code>&lt;style&gt;</code> elements and adds a vendor prefix where needed</li>
		<li>Processes elements with a <code>style</code> attribute and adds a vendor prefix where needed</li>
		<li>Takes care of <strong>new</strong> <code>&lt;link&gt;</code> or <code>&lt;style&gt;</code> elements, <code>style</code> attribute changes and CSSOM changes (<a href="#dynamic-dom">requires plugin</a>)</li>
		<li>Lets <strong>jQuery</strong>’s <code>.css()</code> method get and set unprefixed properties (<a href="#jquery">requires plugin</a>)</li>
	</ul>
</section>
<section id="limitations">
	<h1>Limitations</h1>
	<ul class="drawbacks">
		<li>Prefixing code in <code>@import</code>-ed files is not supported</li>
		<li>Prefixing <strong>cross-origin</strong> linked stylesheets is not supported, unless they are <a href="http://enable-cors.org/" target="_blank">CORS-enabled</a></li>
		<li>Unprefixed linked stylesheets won’t work <strong>locally</strong> in Chrome and Opera. <a href="#local-xhr">You can change that for yourself</a> though.</li>
		<li>Unprefixed <strong>values</strong> in inline styles (in the <code>style</code> attribute) won’t work in IE and Firefox &lt; 3.6. <strong>Properties</strong> as well in Firefox &lt; 3.6.</li>
	</ul>
</section>
</div>

<div class="section-container">
<section id="demo">
	<h1>Demo?</h1>
	<p>Check <a href="css/style.css">this page’s stylesheet</a> ;-)</p>
	<p>You can also visit the <a href="#test-drive">Test Drive</a> page, type in any code you want and check out how it would get prefixed for the current browser.</p>
</section>

<section id="howto">
	<h1>How to use</h1>
	<p>Just include <code>prefixfree.js</code> anywhere in your page. It is recommended to put it right after the stylesheets, to minimize <abbr title="Flash Of UnCSS3-ed Content">FOUC</abbr>
	<p>That’s it, you’re done!</p>
</section>
</div>

<section id="browser-support">
	<h1>Browser support</h1>
	<p>The target browser support is <strong>IE9+</strong>, <strong>Opera 10+</strong>, <strong>Firefox 3.5+</strong>, <strong>Safari 4+</strong> and <strong>Chrome</strong> on desktop and <strong>Mobile Safari</strong>, <strong>Android browser</strong>, <strong>Chrome</strong> and <strong>Opera Mobile</strong> on mobile.</p>
	<p>If it doesn’t work in any of those, it’s a bug so please <a href="https://github.com/LeaVerou/prefixfree/issues">report it</a>. Just before you do, please make sure that it’s not because the browser doesn’t support a CSS3 feature at all, even with a prefix.</p>
	<p>In older browsers like IE8, nothing will break, just properties won’t get prefixed. Which wouldn’t be useful anyway as IE8 doesn’t support much CSS3 ;)</p>
</section>

<section id="test-drive" class="page">
	<h1>Test drive</h1>
	<p>Test the prefixing that -prefix-free would do for this browser, by writing some CSS below:</p>
	<textarea id="source">@keyframes rotate {
    from { transform: rotate(15deg) }
    to { transform: rotate(375deg) }	
}

.download {
   position: absolute;
   top: 1em;
   left: -1.5em;
   width: 6em;
   height: 6em;
   padding: 1em 0;
   background: #80A060;
   background-image: linear-gradient(90deg, transparent, rgba(10,0,0,.3)),linear-gradient(transparent, transparent);
   color: white;
   line-height: 1;
   font-size: 140%;
   text-align: center;
   text-decoration: initial;
   text-shadow: .08em .08em .2em rgba(0,0,0,.6);
   border-radius: 50%;
   box-shadow: .1em .2em .4em -.2em black;
   box-sizing: border-box;
   transform: rotate(15deg);
   animation: rotate;
   cursor: zoom-in;
}

:read-write {}</textarea>
	<textarea id="prefixed" readonly></textarea>
</section>


<section id="faq" class="page">
	<h1>FAQ</h1>
	
	<section>
		<h1>What if I actually want to target only a specific prefix?</h1>
		<p>Properties/values etc that <strong>already</strong> have a prefix won’t be altered. However, if you use the unprefixed property/value etc after the prefixed properties, you might run into <a href="https://github.com/LeaVerou/prefixfree/issues/16#issuecomment-2428237" target="_blank">issue #16</a>.
		For those cases, -prefix-free adds a class on the root element (the <code>&lt;html&gt;</code> element in HTML) with the same name as the current prefix. So for example, to solve the problem presented in the above issue, you could do:</p>
		<pre>.myselector {
    transform: rotate(15deg);
}
.-webkit- .myselector {
    transform: rotate(15deg) rotateX(0);
}</pre>
		<p>It’t not ideal, but it’s a solution, until a more intuitive way to deal with these cases is added in -prefix-free.</p>
		<p>Please note that in unsupported browsers like IE8, no such class will be added.</p>
	</section>
	

	<section>
		<h1>How do I exclude specific files from being prefixed?</h1>
		<p>You can exclude a file from being prefixed by adding the <code>data-noprefix</code> attribute to the <code>&lt;link&gt;</code> or <code>&lt;style&gt;</code> element. For example:</p>
		<pre>&lt;link href=&quot;//example.com/style.css&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; data-noprefix&gt;</pre>
	</section>

	<section id="local-xhr">
		<h1>How do I enable local testing?</h1>
		<p>Firefox (and IE?) natively support local XHR, so -prefix-free will work fine locally with them.</p>
		<p>To enable local XHR for <strong>Chrome</strong>, you need to run it with the flag <code>--allow-file-access-from-files</code>.</p>
		<p>To enable local XHR for <strong>Opera</strong>, you have to go to <a href="opera:config#UserPrefs|AllowFileXMLHttpRequest">opera:config#UserPrefs|AllowFileXMLHttpRequest</a>, check that option and Save.</p>
	</section>
	
	<section>
		<h1>Something like this belongs to the server-side</h1>
		<p>A server side script would need to add all prefixes, making the size of the CSS file considerably larger. Also, it should maintain a list of features that need prefixes, or add them all and unnecessarily bloat the stylesheet. -prefix-free automatically detects what needs a prefix and what doesn’t.</p>
		<p>Also, a common argument against doing this on the client side, is that it makes the design rely on JavaScript. However, that is completely false: If JS is disabled, only some of the CSS3 won’t show. But if your design <em>relies</em> on CSS3 to be functional, you have bigger problems bro.</p>
		<p>You can read some more about this in my recent <a href="http://css-tricks.com/14792-five-questions-with-lea-verou/#lea-question-2">CSS Tricks interview</a></p>
		<p>But every solution has its own pros and cons. If you would feel more comfortable with a server-side script, use that and don’t troll me please. Remember: nobody forced you to use -prefix-free. <strong>KTHXBAI ☺</strong></p>
	</section>
</section>

<section id="plugins" class="page">
	<h1>Plugins</h1>
	<p>Extra code on top of -prefix-free that makes it more flexible, integrates it with different APIs etc</p>
	
	<section id="dynamic-dom">
		<h1>Dynamic DOM plugin</h1>
		<p>Originally a part of -prefix-free, it’s now a separate plugin. It makes -prefix-free take care of:</p>
		<ul class="features">
			<li><strong>New</strong> <code>&lt;link&gt;</code> and <code>&lt;style&gt;</code> added to the document afterwards</li>
			<li><strong>New</strong> elements with a <code>style</code> attribute added to the document afterwards</li>
			<li><code>style</code> attribute changes through <code>setAttribute()</code> (except in Webkit)</li>
			<li>Getting and setting unprefixed properties through the CSSOM, like:
				<pre>element.style.transform = 'rotate(10deg)';</pre>
			</li>
		</ul>
		Things to be aware of:
		<ul class="drawbacks">
			<li>Mutation events have a reputation of being slow, and they are the only way to do stuff when an attribute changes or new elements get added</li>
			<li><code>style</code> attribute modifications will not work in Webkit</li>
			<li>
				<em>Setting</em> unprefixed CSSOM properties, like:
				<pre>element.style.transform = 'rotate(5deg)';</pre>
			 	will not work in Chrome (<em>reading</em> will)
			 </li>
		</ul>
		<p>Get the Dynamic DOM plugin now:</p>
		<ul>
			<li><a href="https://raw.github.com/LeaVerou/prefixfree/gh-pages/plugins/prefixfree.dynamic-dom.js">prefixfree.dynamic-dom.js</a></li>
			<li><a href="https://raw.github.com/LeaVerou/prefixfree/gh-pages/plugins/prefixfree.dynamic-dom.min.js">prefixfree.dynamic-dom.min.js</a></li>
		</ul>
	</section>
	
	<section id="jquery">
		<h1>jQuery plugin</h1>
		<p>A tiny plugin (I didn’t even bother minifying it as it’s so small) that lets you set/get unprefixed CSS properties through jQuery's <code>.css</code> method.</p>
		<p>Get the jQuery plugin now:</p>
		<ul>
			<li><a href="https://raw.github.com/LeaVerou/prefixfree/gh-pages/plugins/prefixfree.jquery.js">prefixfree.jquery.js</a></li>
		</ul>
	</section>
	
	<section id="viewport-units">
		<h1>Viewport-relative units</h1>
		<p>A static polyfill for the new <a href="http://www.w3.org/TR/css3-values/#viewport-relative-lengths">vw, vh, vmin, vmax units</a>.</p>
		<ul class="features">
			<li>Will do nothing if the units are supported natively.</li>
		</ul>
		Limitations:
		<ul class="drawbacks">
			<li>It’s not dynamic. The lengths are replaced once, and then they function as normal CSS pixel values. So, they won’t update when the window is resized, but only on load.</li>
		</ul>
		<ul>
			<li><a href="https://raw.github.com/LeaVerou/prefixfree/gh-pages/plugins/prefixfree.viewport-units.js">prefixfree.viewport-units.js</a></li>
		</ul>
	</section>
	
	<section id="viewport-units">
		<h1>CSS Variables</h1>
		<p>Enables rudimentary <a href="http://www.w3.org/TR/css-variables/">CSS variables</a> support.</p>
		<ul class="features">
			<li>If a prefixed implementation is available, it will add the necessary prefixes and use that</li>
			<li>It supports overwriting the variable value</li>
		</ul>
		Limitations:
		<ul class="drawbacks">
			<li>Doesn’t support scoping. Every variable is in the global scope and every subsequent declaration of the same variable overwrites the previous ones, regardless of scoping</li>
			<li>It’s not dynamic. Variables are replaced once, and then they function as normal CSS values</li>
		</ul>
		<ul>
			<li><a href="https://raw.github.com/LeaVerou/prefixfree/gh-pages/plugins/prefixfree.vars.js">prefixfree.vars.js</a></li>
		</ul>
	</section>
</section>

<footer>
	<a href="http://twitter.com/prefixfree" target="_blank">@prefixfree</a>
	✿ <a href="https://github.com/LeaVerou/prefixfree/commits/gh-pages.atom" target="_blank">Commits feed</a>
	✿ Made by <a href="http://lea.verou.me/">Lea Verou</a> with care
</footer>

<script src="index.js"></script>

<a href="http://twitter.com/share" class="twitter-share-button" data-count="vertical" data-via="prefixfree" data-related="LeaVerou">Tweet</a>
<script src="http://platform.twitter.com/widgets.js"></script>

<script>var _gaq = [['_setAccount', 'UA-25106441-4'],['_trackPageview']];</script>
<script src="http://www.google-analytics.com/ga.js" async></script>

</body>
</html>